package com.jic.product.controller.store;

import com.alibaba.fastjson.JSONObject;
import com.jic.common.base.vo.PageResult;
import com.jic.common.base.vo.RestResult;
import com.jic.product.constant.consist.ResponseCode;
import com.jic.product.model.entity.MStoreBalance;
import com.jic.product.model.entity.MStoreDicts;
import com.jic.product.model.entity.MStoreOperateLog;
import com.jic.product.model.entity.MStoreOperateProductlog;
import com.jic.product.model.vo.request.MStoreOperateProductInfoRequest;
import com.jic.product.model.vo.request.MStoreOperateRequest;
import com.jic.product.model.vo.response.MStoreCheckResponse;
import com.jic.product.model.vo.response.MStoreOperateResponse;
import com.jic.product.service.MStoreBalanceService;
import com.jic.product.service.MStoreDictsService;
import com.jic.product.service.MStoreOperateProductInfoService;
import com.jic.product.service.MStoreOperateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 建投数据科技(山东)有限公司
 * @date: 2020-04-27 16:45:54
 */
@RestController
@Slf4j
@RequestMapping("/mStoreOperate")
@Api(tags = " [库存操作流水记录表;]控制类-PC")
public class MStoreOperateController {
    @Autowired
    private MStoreOperateService service;

    @Autowired
    private MStoreBalanceService mStoreBalanceService;

    @Autowired
    private MStoreOperateProductInfoService mStoreOperateProductInfoService;

    @Autowired
    private MStoreDictsService mStoreDictsService;

    /**
     * 新增记录
     *
     * @param request 新增[库存操作流水记录表;]请求参数
     * @return MStoreOperateResponse 新增[库存操作流水记录表;]响应参数
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:04
     */
    @ApiOperation(value = "新增[库存操作流水记录表;]记录")
    @PostMapping("/save")
    @ResponseBody
    public RestResult<Long> save(@RequestBody MStoreOperateRequest request) throws Throwable {
        MStoreOperateLog mStoreOperate = new MStoreOperateLog();
        BeanUtils.copyProperties(request, mStoreOperate);
        long id = service.save(mStoreOperate);
        return RestResult.success(id);
    }

    /**
     * 新增或修改记录
     *
     * @param request 新增或修改[库存操作流水记录表;]请求参数
     * @return MStoreOperateResponse 新增或修改[库存操作流水记录表;]响应参数
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:04
     */
    @ApiOperation(value = "保存或更新[库存操作流水记录表;]")
    @PostMapping("/saveOrUpdate")
    @ResponseBody
    public RestResult<Boolean> saveOrUpdate(@Validated @RequestBody MStoreOperateRequest request) throws Throwable {
        return RestResult.success(service.saveOrUpdate(request));
    }


    /**
     * 修改[库存操作流水记录表]的状态;
     *
     * @param request 新增或修改[库存操作流水记录表;]请求参数
     * @return MStoreOperateResponse 修改[库存操作流水记录表]响应参数
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:04
     */
    @ApiOperation(value = "保存或更新[库存操作流水记录表]")
    @PostMapping("/updateCheckStatus")
    @ResponseBody
    public RestResult<Long> updateCheckStatus(@Validated @RequestBody MStoreOperateRequest request) throws Throwable {
        MStoreOperateLog mStoreOperate = new MStoreOperateLog();
        BeanUtils.copyProperties(request, mStoreOperate);
        long id = service.updateCheckStatus(mStoreOperate);
        return RestResult.success(id);
    }

    /**
     * 删除记录
     *
     * @param request 删除[库存操作流水记录表;]请求参数
     * @return MStoreOperateResponse 删除[库存操作流水记录表;]响应参数
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:04
     */
    @ApiOperation(value = "删除[库存操作流水记录表;]记录")
    @PostMapping("/delete")
    @ResponseBody
    public RestResult<Long> delete(@RequestBody MStoreOperateRequest request) throws Throwable {
        MStoreOperateLog mStoreOperate = new MStoreOperateLog();
        BeanUtils.copyProperties(request, mStoreOperate);
        long flag = service.deleteByPrimaryKey(mStoreOperate);
        return RestResult.success(flag);
    }

    /**
     * 修改记录
     *
     * @param request 修改[库存操作流水记录表;]请求参数
     * @return MStoreOperateResponse 修改[库存操作流水记录表;]响应参数
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:04
     */
    @ApiOperation(value = "修改[库存操作流水记录表;]记录")
    @PostMapping("/update")
    @ResponseBody
    public RestResult<Long> update(@RequestBody MStoreOperateRequest request) throws Throwable {
        MStoreOperateLog mStoreOperate = new MStoreOperateLog();
        BeanUtils.copyProperties(request, mStoreOperate);
        long flag = service.updateByPrimaryKeySelective(mStoreOperate);
        return RestResult.success(flag);
    }

    /**
     * 单表查询详情信息
     *
     * @param request 查询[库存操作流水记录表;]详情请求参数
     * @return MStoreOperateResponse 查询[库存操作流水记录表;]详情响应参数
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:04
     */
    @PostMapping("/getByPrimaryKey")
    @ApiOperation(value = "查询[库存操作流水记录表;]详情")
    @ResponseBody
    public RestResult<MStoreOperateResponse> getByPrimaryKey(@Validated @RequestBody MStoreOperateRequest request) {
        log.info("查询详情请求参数入参，{}", JSONObject.toJSONString(request));
        if (request != null && request.getId() != null) {

            MStoreOperateLog mStoreOperate = new MStoreOperateLog();
            BeanUtils.copyProperties(request, mStoreOperate);
            MStoreOperateLog result = service.getByPrimaryKey(mStoreOperate);
            log.info("查询详情请求参数出参，{}", JSONObject.toJSONString(result));
            if (result == null) {
                return RestResult.error(ResponseCode.EXCEPTION, "记录不存在");
            }
            MStoreOperateResponse bo = new MStoreOperateResponse();
            BeanUtils.copyProperties(result, bo);
            //判断单据类型
            MStoreDicts mStoreDicts = new MStoreDicts();
            mStoreDicts.setId(result.getOperateId());
            MStoreDicts storeDicts = mStoreDictsService.getByPrimaryKey(mStoreDicts);
            if (null != storeDicts) {
                bo.setOperateType(Integer.valueOf(storeDicts.getType()));
            }
            return RestResult.success(bo);
        }
        log.info("查询详情请求结束");
        return RestResult.success(null);
    }

    /**
     * 分页查询
     *
     * @param request 分页查询请求参数
     * @return 分页列表
     * @throws Throwable 业务异常和系统异常
     */
    @PostMapping("/listPage")
    @ApiOperation(value = " 分页查询实体库流水列表 ")
    @ResponseBody
    public RestResult<PageResult<MStoreOperateResponse>> listPage(@RequestBody MStoreOperateRequest request) throws Throwable {
//        MStoreOperate param = new MStoreOperate();
//        BeanUtils.copyProperties(request, param);
//        param.setCode(request.getDocumentsNumber());//单据编号
//        param.setStoreName(request.getWarehouseCode());//仓库编码或仓库名称
        return RestResult.success(service.listPageBySelective(request, request.getPageNum(), request.getPageSize()));
    }

    @PostMapping("/listOpratePage")
    @ApiOperation(value = " 分页查询事务单列表 ")
    @ResponseBody
    public RestResult<PageResult<MStoreOperateResponse>> listOpratePage(@RequestBody MStoreOperateRequest request) throws Throwable {
        return RestResult.success(service.listOpratePageBySelective(request, request.getPageNum(), request.getPageSize()));
    }

    @PostMapping("/listOperateAndProductPage")
    @ApiOperation(value = " 分页查询盘点列表 ")
    @ResponseBody
    public RestResult<PageResult<MStoreCheckResponse>> listOperateAndProductPage(@RequestBody MStoreOperateRequest request) throws Throwable {
        return RestResult.success(service.listOperateAndProductPage(request, request.getPageNum(), request.getPageSize()));
    }

    /**
     * M_STORE_OPERATE 查询列表（不分页）
     *
     * @param request 前端请求参数
     */
    @PostMapping("/listAll")
    @ApiOperation(value = "不分页查询 [库存操作流水记录表;] ")
    @ResponseBody
    public RestResult<List<MStoreOperateResponse>> listMStoreOperateAllRecord(@RequestBody MStoreOperateRequest request) throws Throwable {
        MStoreOperateLog mStoreOperate = new MStoreOperateLog();
        BeanUtils.copyProperties(request, mStoreOperate);

        List<MStoreOperateLog> list = service.listAllRecord(mStoreOperate);
        List<MStoreOperateResponse> responseList = list.stream().map(temp -> {
            MStoreOperateResponse bo = new MStoreOperateResponse();
            BeanUtils.copyProperties(temp, bo);
            return bo;
        }).filter(item -> item != null).collect(Collectors.toList());
        return RestResult.success(responseList);
    }

    @ApiOperation(value = "出库操作")
    @PostMapping("/outStock")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public RestResult<Long> saveProductInfo(@RequestBody MStoreOperateRequest request) throws Throwable {
        long flag = 0;
        if (request.getId() != null && request.getId() > 0) {
            List<MStoreOperateProductInfoRequest> products = request.getProducts();
            MStoreOperateLog operate = new MStoreOperateLog();
            operate.setId(request.getId());
            //根据主键查询对应operate记录
            MStoreOperateLog result = service.getByPrimaryKey(operate);
            Long type = result.getOperateId();
            if (type == null) {
                return RestResult.error("9999", "事务单操作类型为空");
            }
            if (result != null) {
                if (products != null && products.size() > 0) {
                    for (MStoreOperateProductInfoRequest product : products) {
                        //查询商品对应台账信息
                        MStoreBalance queryBalanceParams = new MStoreBalance();
                        queryBalanceParams.setProductId(product.getProductId());
                        queryBalanceParams.setStoreId(request.getStoreId());
                        List<MStoreBalance> balances = mStoreBalanceService.listAllRecord(queryBalanceParams);
                        MStoreBalance balance = balances.get(0);
                        if (balances == null && balances.size() == 0) {
                            return RestResult.error("9999", "台账记录不存在");
                        }
                        //根据operateId找到对应的单据操作类型
                        if (null != type && type > 9) {//减库操作
                            //判断减少的数量和台账可用数量大小
                            long value = product.getApplyNum() - balance.getAvailable();
                            if (value < 0) {//库存余额充足 可以直接减
                                balance.setAvailable(balance.getAvailable() - product.getApplyNum());
                                balance.setTotal(balance.getTotal() - product.getApplyNum());
                                balance.setDeptId(request.getAdminOperate().getDeptId());
                                mStoreBalanceService.saveOrUpdate(balance);
                                //更新对应product_info实际出库数量
                                product.setActualNum(product.getApplyNum());
                                MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
                                BeanUtils.copyProperties(product, mStoreOperateProductlog);
                                mStoreOperateProductInfoService.saveOrUpdate(mStoreOperateProductlog);
                            } else {
                                //如果申请减少的数量大于可用余额 则把库存减少至0
                                balance.setAvailable(0L);
                                balance.setTotal(0L);
                                mStoreBalanceService.saveOrUpdate(balance);

                                //更新对应product_info实际出库数量
                                product.setActualNum(balance.getAvailable());
                                MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
                                BeanUtils.copyProperties(product, mStoreOperateProductlog);
                                mStoreOperateProductInfoService.saveOrUpdate(mStoreOperateProductlog);
                            }
                        } else {//加库操作

                        }
                    }
                } else {
                    return RestResult.error("9999", "事务单详细列表不能为空");
                }
            } else {
                return RestResult.error("9999", "缺少事务单主体信息");
            }
        } else {
            return RestResult.error("9999", "缺少事务单主体信息");
        }


        return RestResult.success(flag);
    }


    /**
     * 实体库存变动流水列表分页查询
     *
     * @param request 分页查询请求参数
     * @return 分页列表
     * @throws Throwable 业务异常和系统异常
     */
    @PostMapping("/operateListPage")
    @ApiOperation(value = " 实体库存变动流水列表分页查询 ")
    @ResponseBody
    public RestResult<PageResult<MStoreOperateResponse>> operateListPage(@RequestBody MStoreOperateRequest request) throws Throwable {
        return RestResult.success(service.operateListPage(request, request.getPageNum(), request.getPageSize()));
    }

    /**
     * 实体库存变动流水导出（不分页）
     *
     * @param request 前端请求参数
     */
    @PostMapping("/listMStoreOperateExcel")
    @ApiOperation(value = "不分页查询 [库存操作流水记录表;] ")
    @ResponseBody
    public RestResult<List<MStoreOperateResponse>> listMStoreOperateExcel(@RequestBody MStoreOperateRequest request) throws Throwable {
        List<MStoreOperateLog> list = service.listMStoreOperateExcel(request);
        List<MStoreOperateResponse> collect = list.stream().map(temp -> {
            MStoreOperateResponse bo = new MStoreOperateResponse();
            BeanUtils.copyProperties(temp, bo);
            return bo;
        }).filter(item -> item != null).collect(Collectors.toList());
        return RestResult.success(collect);
    }
}

